perm filename NETSUB.MAC[IP,SYS]1 blob
sn#690060 filedate 1982-12-09 generic text, type T, neo UTF8
universal NetSub - common subroutines for universal network
subttl provan - 1982
search f,s
search NetDef ; get network definition
search MacTen ; make coding convenient
$reloc
$high
XP VNetSb,1000 ; first version
NetSub: ENTRY NetSub ;TO LOAD ON LIB SEARCH
comment \
common subroutines which will be needed by most everybody
to support ip/tcp and other protocols
\
subttl NxtByt
;++
; Functional description:
;
; subroutine to read the next byte form a data stream. a lot
; like InByte in function, except the stream is discribed in
; p1, p2, and p3, instead of in the DDB, and the buffers are
; not discarded after being emptied.
;
;
; Calling sequence:
;
; move p1,<next buffer>
; move p2,<buffer pointer to next data>
; move p3,<count of bytes left in this buffer>
; pushj p,NxtByt
; <returns here if buffers are exhausted>
; <returns here with next byte in T1>
;
; Input parameters:
;
; P1 - the pointer to the next buffer in the stream.
; P2 - ILDB pointer to next byte in current buffer.
; P3 - count of bytes left in this buffer
;
; to start a buffer stream, put a pointer to the first buffer in
; P1 and zero P3. then leave P1, P2 and P3 alone between
; calls.
;
; Output parameters:
;
; T1 - next byte in stream.
;
; Implicit inputs:
;
; none.
;
; Implicit outputs:
;
; none.
;
; Routine value:
;
; returns non-skip if there are no more data in the stream.
;
; Side effects:
;
; none.
;
;--
NxtBuf:
pjumpe p1,cpopj## ; non-skip return if no next buffer.
hrrzi p2,NBHLen(p1) ; this is now the current buffer:
; point at first data word.
hrli p2,(point 8,) ; ILDB pointer to first byte of
; this word
load. p3,NBHCnt,(p1) ; load up count of byte in this buffer
load. p1,NBHNxt,(p1) ; remember next buffer in stream
NxtByt::
sojl p3,NxtBuf ; move on to the next buffer
ildb t1,p2 ; get next byte in this buffer
pjrst cpopj1## ; skip return
subttl NxtFls
;++
; Functional description:
;
; skip over bytes in the data stream described by P1, P2, and P3.
;
;
; Calling sequence:
;
; move P1,<next buffer in stream>
; move P2,<ILDB pointer to next byte in stream>
; move P3,<count of bytes left in this buffer>
; move t1,<number of byte to skip>
; pushj p,NxtFls
; <not that many bytes in stream>
; <all flushed>
;
; Input parameters:
;
; see NxtByt for P1, P2 and P3
; T1 - number of bytes to skip over.
;
; Output parameters:
;
; none.
;
; Implicit inputs:
;
; none.
;
; Implicit outputs:
;
; none.
;
; Routine value:
;
; returns non-skip if there are not enough bytes in the stream.
;
; Side effects:
;
; none.
;--
NxtFls::
push p,t2 ; save t2 for counting
move t2,t1 ; get count in a safe place
FlusLp:
sojge t2,t2poj1## ; no more to flush. skip return.
pushj p,NxtByt ; read and discard next byte
pjrst t2popj## ; restore T2 and return non-skip.
jrst FlusLp ; continue flushing option
subttl OptFls
;++
; Functional description:
;
; flush an option (ip or tcp, for example) from the data stream
; described by P1, P2, and P3. this routine assumes that the
; caller has just read the type field and wants to throw out
; the rest of the option. this routine read the next byte, which
; should be the length field, and skips over that many bytes in the
; stream.
;
;
; Calling sequence:
;
; move P1,<next buffer in stream>
; move P2,<ILDB pointer to next byte in stream>
; move P3,<count of bytes left in this buffer>
; pushj p,NxtFls
; <end of stream encountered>
; <all flushed>
;
; Input parameters:
;
; see NxtByt for P1, P2 and P3
;
; Output parameters:
;
; none.
;
; Implicit inputs:
;
; none.
;
; Implicit outputs:
;
; none.
;
; Routine value:
;
; returns non-skip if end of stream was encounter either during
; the read of the length or during the skipping of the length.
;
; Side effects:
;
; none.
;--
OptFls::
pushj p,NxtByt ; try for a length field
popj p, ; can't get it. end of stream
subi t1,2 ; remember we've read the type
; and the length bytes.
pjrst NxtFls ; skip that many bytes and return
subttl NxtWrd
;++
; Functional description:
;
; read in a full 32-bit word from the data stream described by
; P1, P2, and P3.
;
;
; Calling sequence:
;
; move P1,<next buffer in stream>
; move P2,<ILDB pointer to next byte in stream>
; move P3,<count of bytes left in this buffer>
; pushj p,NxtWrd
; <not enough bytes for this word>
; <word in T1, right justified>
;
; Input parameters:
;
; see NxtByt
;
; Output parameters:
;
; T1 - next 4 bytes from data stream as a 32-bit word, right
; justified.
;
; Implicit inputs:
;
; none.
;
; Implicit outputs:
;
; none.
;
; Routine value:
;
; returns non-skip if there are not enough bytes in the stream.
;
; Side effects:
;
; none.
;--
NxtWrd::
push p,t2 ; save a scratch
push p,t3 ; and another
movei t3,4 ; number of bytes in a word
setz t2, ; start with word empty
NWrdLp: pushj p,NxtByt ; get next byte into T1
jrst NWdOut ; bad return
lshc t1,-8 ; shift byte into word builder
sojg t3,NWrdLp ; loop if not done.
move t1,t2 ; get word left justified
lsh t1,-4 ; right justify it
aos -2(p) ; set skip return
NWdOut: pop p,t3 ; restore
pjrst t2popj## ; restore T2 and return as set
subttl RplWrd
;++
; Functional description:
;
; replacethe next full 32-bit word from the data stream described by
; P1, P2, and P3 by the value passed in in T1.
;
;
; Calling sequence:
;
; move P1,<next buffer in stream>
; move P2,<ILDB pointer to next byte in stream>
; move P3,<count of bytes left in this buffer>
; move t1,<value to be inserted>
; pushj p,NxtWrd
; <not enough bytes for this word>
; <word before replacement in T1, right justified>
;
; Input parameters:
;
; see NxtByt for P1, P2, and P3.
; T1 - right justified 32 bit word to be placed in the next 4 bytes
; of the stream.
;
; Output parameters:
;
; T1 - next 4 bytes from data stream as a 32-bit word, right
; justified. these are the four bytes which were just
; written over.
;
; Implicit inputs:
;
; none.
;
; Implicit outputs:
;
; none.
;
; Routine value:
;
; returns non-skip if there are not enough bytes in the stream.
;
; Side effects:
;
; none.
;--
RplWrd::
push p,t2 ; save scratch
push p,t3 ; and more
push p,t4 ; etc.
move t4,t1 ; get word to be written
lsh t4,4 ; left justify it.
movei t3,4 ; number of bytes in a word
setz t2, ; start with word empty
RWrdLp: pushj p,NxtByt ; get next byte into T1
jrst RWdOut ; bad return
lshc t1,-8 ; shift byte into word builder
exch t2,t4 ; get word to write in correct place
lshc t1,8 ; shift next byte of it up
dpb t1,p2 ; put that byte where we just read.
exch t2,t4 ; put word builder back in
; correct place.
sojg t3,RWrdLp ; loop if not done.
move t1,t2 ; get word left justified
lsh t1,-4 ; right justify it
aos -3(p) ; set skip return
RWdOut: pop p,t4 ; restore
pop p,t3 ; restore
pjrst t2popj## ; restore T2 and return correctly.
SUBTTL IMPBUF ... BUFFER ALLOCATION AND RELEASE ROUTINES
;SUBROUTINE TO ALLOCATE A BUFFER. USES T1,T2,T3.
;CALL:
; PUSHJ P,BUFGET
; ERROR RETURN ...NO MORE BUFFERS
; OK RETURN, BUFFER ADDRESS IN T1
BUFGET::
SOSGE BUFNUM ;ANY FREE BUFFERS?
JRST BUFGT3 ;NO
MOVSI T3,IMPM36## ;-<# OF BUFFERS>/36
BUFGT1: SETCM T1,IMPBFT##(T3) ;GET COMPLEMENT OF BUSY BITS
JFFO T1,BUFGT2 ;FIND FIRST FREE BUFFER(NON-ZERO BIT)
AOBJN T3,BUFGT1
STOPCD CPOPJ##,STOP,BBD, ;++BIT TABLE AND BUFNUM DISAGREE
BUFGT3: AOSLE T2,BUFNUM ;NO FREE BUFFERS
JRST BUFGET ;TRY AGAIN IF NOT EMPTY
AOS BUFERR ;COUNT NUMBER OF TIMES BUFFERS RAN OUT
POPJ P,
BUFGT2: MOVNI T2,(T2) ;SET THE BUSY BIT IN THE ALLOCATION TABLE
MOVSI T1,(1B0)
LSH T1,(T2)
IORM T1,IMPBFT##(T3)
MOVN T1,T2 ;GET BACK BIT POSITION IN WORD
IMULI T3,↑D36 ;COMPUTE BUFFER NUMBER (0 TO IMPBFN-1)
ADDI T1,(T3)
IMULI T1,IMPBFS## ;CONVERT TO ADDRESS OF BUFFER
ADD T1,IMPBUF##
IFN DEBUG,<
CAML T1,IMPBFE## ;MAKE SURE WE GOT A LEGAL ADDRESS
STOPCD CPOPJ,STOP,BAL, ;++BAD ADDRESS ALLOCATED
>
AOS (P) ;OK, PRESET SKIP RETURN
;SUBROUTINE TO ZERO A BUFFER. ADDRESS IN T1.
BFCLR: HRLI T2,(T1) ;MAKE BLT POINTER
HRRI T2,1(T1)
SETZM (T1) ;CLEAR FIRST CELL
BLT T2,IMPBFS##-1(T1) ;WIPE THE REST
POPJ P,
;SUBROUTINE TO RELEASE ALL BUFFERS IN A STREAM. ENTER WITH
; FIRST BUFFER ADDRESS IN T1.
;CALL:
; MOVE T1, [ADDRESS OF FIRST BUFFER]
; PUSHJ P,RELBUF
; ALWAYS RETURN HERE
RELBUF::
ANDI T1,-1 ;MASK OUT ALL BUT ADDRESS
RELBF1: JUMPE T1,CPOPJ## ;DONE IF ZERO ADDRESS
IFN DEBUG,<
CAML T1,IMPBUF## ;AVOID USING GARBAGE ADDRESSES
CAML T1,IMPBFE##
STOPCD CPOPJ,STOP,BAR, ;++BAD ADDRESS RELEASED
>
HRL T1,(T1) ;GET NEXT BUFFER ADDRESS
HLLM T1,(P) ;SAVE IT
IFN DEBUG,<
PUSHJ P,BFCLR ;CLEAR BUFFER TO MAKE DEBUGGING EASIER
>
PUSHJ P,BUFREL ;RELEASE THIS ONE
HLRZ T1,(P) ;GET NEXT BUFFER ADDRESS AGAIN
JRST RELBF1 ;LOOP
;SUBROUTINE TO RELEASE A BUFFER.
;CALL:
; MOVE T1,[APPROXIMATE ADDRESS(WITHIN LIMITS OF BUFFER)]
; PUSHJ P,BUFREL
; ALWAYS RETURN HERE
BUFREL::
ANDI T1,777777 ;ONLY RIGHT HALF
CAML T1,IMPBUF## ;CHECK THAT IT'S A GOOD IMP BUFFER ADDRESS
CAML T1,IMPBFE## ; ELSE WE TRASH FILSER CORE AND OTHER STUFF
popj p, ; must be a fixed buffer
SUB T1,IMPBUF## ;GET BUFFER NUMBER
IDIVI T1,IMPBFS##
SKIPE IBFHLT## ;INPUT DESPERATE?
JRST BUFRL1 ;YES
IDIVI T1,↑D36 ;NO, CONVERT BUFFER NUMBER TO
MOVNS T2 ; ALLOCATION WORD AND BIT. SET THE BIT
MOVSI T3,(1B0)
LSH T3,(T2)
IFN DEBUG,<
TDNN T3,IMPBFT##(T1) ;AVOID TRYING TO FREE A FREE BUFFER
STOPCD CPOPJ,DEBUG,FFB, ;++FREEING A FREE BUFFER
>
ANDCAM T3,IMPBFT##(T1) ;CLEAR THE BUSY BIT
AOS BUFNUM ;BUMP BUFFER COUNT
POPJ P,
;HERE TO GIVE BUFFER TO INPUT ROUTINE
BUFRL1: IMULI T1,IMPBFS## ;GET BUFFER ADDRESS
ADD T1,IMPBUF##
MOVE T2,T1 ;SET UP FOR BFCLR
PUSHJ P,BFCLR ;WIPE THE BUFFER
JRSU INON## ;TELL impser we have something SECTION
subttl CSmByt
;++
; Functional description:
;
; deal with a single byte for checksumming purposes.
; decides whether this is an even numbered byte or an
; odd number, and adds it appropriately into the 16 bit
; running checksum kept in P3.
;
;
; Calling sequence:
;
; move t1,byte
; setz p3, ; first call. unmolested between calls.
; pushj p,CSmByt
; <always returns here, running checksum in right half of P3>
;
; Input parameters:
;
; T1 - byte to checksum
; P3 - should be set to zero before first call, left undisturbed
; between calls.
; RH - checksum up until now in the right half.
; LH - low bit in left half indicates even or oddness of byte number.
;
; Output parameters:
;
; P3 - right half word: 16 bit ones compliment checksum to this point.
; left half word: bit 17 is on if an odd number of byte were seen.
;
; Implicit inputs:
;
; none.
;
; Implicit outputs:
;
; none.
;
; Routine value:
;
; none.
;
; Side effects:
;
; none.
;--
CSmByt::
ifn FtChck,< ; do this only if checksumming
tlcn p3,1 ; is the "second byte" bit on?
lsh t1,↑d8 ; no. move over to it's place.
add p3,t1 ; add this byte into running checksum.
trze p3,<1←↑d16> ; overflow out of 16 bits?
aos p3 ; yes. end-around carry
> ; end of IFN FtChck
popj p, ; return
subttl CSmHWd
;++
; Functional description:
;
; deal with a 16 bit byte for checksumming purposes.
; adds it appropriately into the 16 bit running
; checksum kept in P3. it is assumed that this half
; word is not being added to the end: left half of
; P3 (see CSmByt) is left undisturbed.
;
;
; Calling sequence:
;
; move t1,<16 bit "half word">
; setz p3, ; first call. unmolested between calls.
; pushj p,CSmHWd
; <always returns here, running checksum in right half of P3>
;
; Input parameters:
;
; T1 - 16 bit byte to checksum, right justified.
; P3 - should be set to zero before first call to any of the
; checksuming routines, left undisturbed between calls.
; RH - checksum up until now in the right half.
;
; Output parameters:
;
; P3 - right half word: 16 bit ones compliment checksum to this point.
; left half word: just as it was on entry.
;
; Implicit inputs:
;
; none.
;
; Implicit outputs:
;
; none.
;
; Routine value:
;
; none.
;
; Side effects:
;
; none.
;--
CSmHWd::
ifn FtChck,< ; do this only if checksumming
add p3,t1 ; add this byte into running checksum.
trze p3,<1←↑d16> ; overflow out of 16 bits?
aos p3 ; yes. end-around carry
> ; end of IFN FtChck
popj p, ; return
subttl CSmWrd
;++
; Functional description:
;
; deal with a 32 bit word for checksumming purposes.
; adds it appropriately into the 16 bit running
; checksum kept in P3. it is assumed that this half
; word is not being added to the end: left half of
; P3 (see CSmByt) is left undisturbed.
;
;
; Calling sequence:
;
; move t1,<32 bit word>
; setz p3, ; first call. unmolested between calls.
; pushj p,CSmWrd
; <always returns here, running checksum in right half of P3>
;
; Input parameters:
;
; T1 - 32 bit word to checksum, *LEFT* justified.
; P3 - should be set to zero before first call to any of the
; checksuming routines, left undisturbed between calls.
; RH - checksum up until now in the right half.
;
; Output parameters:
;
; P3 - right half word: 16 bit ones compliment checksum to this point.
; left half word: just as it was on entry.
;
; Implicit inputs:
;
; none.
;
; Implicit outputs:
;
; none.
;
; Routine value:
;
; none.
;
; Side effects:
;
; none.
;--
ifn FtChck,< ; do this only if checksumming
CSmWrd::
push p,t1 ; save word out of the way.
move t1,[point 16,(p)] ; point at where it is
movei t2,2 ; want two 16 bit bytes checksummed
pushj p,CSmWds ; do the checksum
jrst tpopj## ; retore T1 and return
>
ife FtChck,< CSmWrd==:cpopj## > ; do nothing if not checksumming
subttl CSmWds
;++
; Functional description:
;
; deal with a 32 bit words for checksumming purposes.
; adds them appropriately into the 16 bit running
; checksum kept in P3. it is assumed that this half
; word is not being added to the end: left half of
; P3 (see CSmByt) is left undisturbed.
;
;
; Calling sequence:
;
; move t1,<ildb pointer to words>
; move t2,<number of 8 bit bytes in the words>
; setz p3, ; first call. unmolested between calls.
; pushj p,CSmWds
; <always returns here, running checksum in right half of P3>
;
; Input parameters:
;
; T1 - ILDB pointer the the words to be checksummed.
; T2 - number of 8 bit bytes to be checksummed. this
; value is truncated if odd.
; P3 - should be set to zero before first call to any of the
; checksuming routines, left undisturbed between calls.
; RH - checksum up until now in the right half.
;
; Output parameters:
;
; P3 - right half word: 16 bit ones compliment checksum to this point.
; left half word: just as it was on entry.
;
; Implicit inputs:
;
; none.
;
; Implicit outputs:
;
; none.
;
; Routine value:
;
; none.
;
; Side effects:
;
; clobber t2.
;--
ifn FtChck,< ; do this only if checksumming
CSmWds: push p,t1 ; save the pointer
lsh t2,-1 ; convert from 8 bytes to 16 bit bytes.
CSmLp: ildb t1,(p) ; get the next byte
pushj p,CSmHWd ; checksum that
sojg t2,CSmLp ; get next byte
jrst tpopj## ; restore T1 and return.
> ; end of IFN FtChck
ife FtChck,< CSmWds==:cpopj## > ; do nothing if not checksumming
subttl GetLed - get leader
;++
; Functional description:
;
; copies a leader into a preassigned storage location, keeping
; a 1's complement checksum of words read in P1.
;
;
; Calling sequence:
;
; move f,PDDB
; move p3,<running checksum>
; move t1,<IDBP pointer to storage space, or 0>
; move t2,<number of bytes in leader>
; pushj p,GetLed
; <not enough bytes in stream for this leader>
; <leader copied>
;
; Input parameters:
;
; F - PDDB
; P3 - checksum of message to this point.
; T1 - an ILDB pointer to the first byte of storage for the leader.
; or 0, if bytes should not be saved anywhere.
; T2 - a count of the number of bytes to be copied.
;
; Output parameters:
;
; P3 - checksum updated
;
; Implicit inputs:
;
; buffer stream.
;
; Implicit outputs:
;
; BIB, storage location indicated in T1
;
; Routine value:
;
; returns non-skip if there are not enough bytes in the indicated
; stream to satisfy the request.
;
; Side effects:
;
; buffers may be deallocated if exhausted.
; T1 and T2 are destroyed.
;--
GetLed::
pushj p,save2## ; save p1 and p2
move p1,t1 ; move pointer to p1
move p2,t2 ; move count to p2
GetLe0: jsp p4,(p4) ; next byte from stream
popj p, ; not enough bytes
skipe p1 ; don't save if not wanted
idpb t1,p1 ; put that byte where requested
pushj p,CSmByt ; include this byte in the checksum
sojg p2,GetLe0 ; loop until copied as many as requested
pjrst cpopj1## ; skip return. found enough bytes.
subttl GetMes
;++
; Functional description:
;
; pull in a message stream from IMP input, tacking it on to the
; end of a possibly nonexistent stream. updates the 1's complement
; checksum of this message in P3.
;
;
; Calling sequence:
;
; move p3,<running checksum for this message>
; move t1,<bytes to copy>
; pushj p,GetMes
; <input ends before stream is full or no more buffers>
; <T1 contains data stream pointer for new data>
;
; Input parameters:
;
; P3 - checksum of this message so far.
;
; T1 - number of bytes to be copied into the stream.
;
; Output parameters:
;
; P3 - checksum of the entire message after checksumming this
; part of it.
;
; T1 - new stream pointer, <LH> first buffer, <RH> last buffer.
;
; Implicit inputs:
;
; input stream of NxtByt.
;
; Implicit outputs:
;
; none.
;
; Routine value:
;
; returns <skip> if all went well. returns <non-skip> if the
; input stream from the IMP ended before the given number of
; bytes was copied or if the network service runs out of
; buffer space during this copy.
;
; Side effects:
;
; read (T1) bytes from the input stream.
; updates running checksum in P3.
;--
GetMes::
pushj p,save2## ; get P1 and P2
skipn p1,t1 ; save the count
pjrst cpopj1## ; nothing to copy. i'm hip.
setz p2, ; nothing seen yet.
GetMe1: pushj p,BufGet ; get a fresh buffer in T1
popj p, ; return if no more buffers.
skipn p2 ; is this is first buffer?
jrst [ ; yes.
hrlz p2,t1 ; remember that it is the first.
jrst GetMe2 ; and continue
]
stor. t1,NBHNxt,(p2) ; no. link it into buffer
; which used to be the last.
GetMe2: hrr p2,t1 ; now make it the new last buffer.
add t1,[point 8,NBHLen] ; convert to pointer to first
; word after the header.
movei t2,NBfByt ; set how many bytes of data there
; are in a fresh buffer.
camge p1,t2 ; is the available space more
; than we want to read?
move t2,p1 ; yes. back off to just what
; we want.
stor. t2,NBHCnt,(p2) ; save this count
sub p1,t2 ; remember we've gotten these bytes
pushj p,GetLed ; read in a brace of data
pjrst [ ; not enough buffers.
hlrz t1,p2 ; load buffer pointer.
pjrst RelBuf ; get rid of all buffers gotten
; so far and give non-skip return.
]
jumpg p1,GetMe1 ; still more? go get another
; buffer and continue.
move t1,p2 ; return new pointer to stream.
pjrst cpopj1## ; all done.
subttl DDBGet
;++
; Functional description:
;
; finds a DDB for this job. if it finds an IMP DDB which this
; job owns but which is in the closed state (i.e., unused), it
; returns that DDB. if it finds a DDB which is not in use, it
; returns that DDB. it clears out the DDB and set the proper
; things to remember this DDB is now in use.
;
;
; Calling sequence:
;
; move j,<job number or 0 if no job>
; scnoff
; pushj p,DDBGet
; <return here if no DDB is available>
; <return here with DDB in F>
;
; Input parameters:
;
; J - job number of current job, or zero if there is no current
; job.
;
; Output parameters:
;
; F - new DDB, all set up
;
; Implicit inputs:
;
; DDB chain
;
; Implicit outputs:
;
; none.
;
; Routine value:
;
; returns non-skip if no DDB could be found.
;
; Side effects:
;
; clobbers T1, T2, and T3
;--
DDBGET::
MOVEI T2,IMPN ;MAXIMUM NUMBER TO CHECK
MOVEI F,IMPDDB## ;START HERE
MOVEI T1,ASSCON!ASSPRG ;FOR ASSIGNMENT TEST
DDBGT1: skipe State(f) ; state closed?
jrst DDBGT2 ;DONT USE IF NOT CLOSED
TDNN T1,DEVMOD(F) ;ASSIGNED?
JRST DDBGT3 ;NO
JUMPE J,DDBGT2 ;IF NO JOB NUMBER, CANT POSSIBLY OWN IT
LDB T3,PJOBN## ;GET OWNER JOB NUMBER
CAMN T3,J ;MINE?
JRST DDBGT4 ;YES
DDBGT2: HLRZ F,DEVSER(F) ;GET NEXT
SOJG T2,DDBGT1 ;LOOP IF MORE TO TEST
POPJ P, ;NONE FREE. ERROR RETURN
;HERE WHEN FOUND A DDB
DDBGT3: DPB J,PJOBN## ;DEPOSIT JOB NUMBER
DDBGT4: MOVEI T1,ASSCON ;ASSIGNED BY CONSOLE BIT
IORM T1,DEVMOD(F) ;ASSIGN IT
PUSHJ P,CLRIMP ;CLEAR IT
SETZM DEVLOG(F) ;ENSURE NO LOGICAL NAME YET
JRST CPOPJ1## ;SKIP RETURN
subttl DDBFls
;++
; Functional description:
;
; flush all data from a DDB. does not release DDB. assumes
; that it knows all about the DDB. any field that should be
; ignored should be zero.
;
;
; Calling sequence:
;
; move f,DDB
; pushj p,DDBFls
; <always returns here>
;
; Input parameters:
;
; F - DDB to be flushed
;
; Output parameters:
;
; none.
;
; Implicit inputs:
;
; DDB
;
; Implicit outputs:
;
; none.
;
; Routine value:
;
; none.
;
; Side effects:
;
; throws out any buffers and BIBs this DDB may point to.
;--
DDBFls::
hrrz t1,IBfThs(f) ; get head of input queue
pushj p,RelBuf ; release the entire queue
hrrz t1,OBfFst(f) ; get first buffer in output
pushj p,RelBuf ; flush it as well
skipe t1,RetrnQ(f) ; get retransmission queue
pushj p,FlsBIB ; flush entire string of them
skipe t1,Future(f) ; get futures queue, if any
pushj p,FlsFMB## ; release futures
setzm State(f) ; make the state 0 (closed, i hope)
pushj p,ItyRel## ; ditch ITY, if any.
pjrst TTIDet## ; disconnect crosspatched IMP.
;SUBROUTINE TO RELEASE A DDB. SHOULD ONLY BE CALLED AFTER
; CLOSING BOTH SIDES.
;CALL:
; MOVE F, [ADDRESS OF DDB]
; PUSHJ P,DDBREL
; ALWAYS RETURN HERE
DDBREL::MOVEI T2,ASSCON ;DEASSIGN DEVICE.
PUSHJ P,RELEA6##
; JRST CLRIMP
;SUBROUTINE TO WIPE A DDB
CLRIMP::
PUSHJ P,IMPWK1## ;CLEAR FLAGS
MOVE T1,[IMPCLR,,IMPDDS-1] ;WIPE ALL IMP-SPECIFIC STUFF
; PJRST DDBCLR
;ROUTINE TO WIPE ARBITRARY PARTS OF AN IMP DDB
; MOVE F,[DDB ADDRESS]
; MOVE T1,[FIRST,,LAST] ;RELATIVE WORDS TO BE ZEROED
; PUSHJ P,DDBCLR
; ALWAYS RETURN HERE--USES T1 AND T2
DDBCLR: ADDI T1,(F) ;MAKE FINAL ADDRESS ABSOLUTE
HLRZ T2,T1 ;GET RELATIVE FIRST ADDRESS
ADDI T2,1(F) ;MAKE IT ABSOLUTE AND ADD ONE
HRLI T2,-1(T2) ;MAKE ABSOLUTE FIRST,,FIRST+1
SETZM -1(T2) ;CLEAR FIRST WORD
BLT T2,(T1) ;CLEAR REST
POPJ P,
subttl MakBIB
;++
; Functional description:
;
; make a buffer information block for the current output buffer.
; also puts it on the retransmission queue, etc.
;
;
; Calling sequence:
;
; move f,DDB
; pushj p,MakBIB
; <returns here if can't get enough monitor free core
; for BIB>
; <returns here if ok>
;
; Input parameters:
;
; f - DDB
;
; Output parameters:
;
; T1 - BIB pointer
;
; Implicit inputs:
;
; DDB
;
; Implicit outputs:
;
; DDB
;
; Routine value:
;
; returns non-skip if request for monitor free core to build
; BIB failed, else returns skip.
;
; Side effects:
;
; adds message to retransmission queue.
;--
MakBIB::
movei t2,BIBLen/4 ; how many 4 word blocks?
pushj p,Get4Wd## ; get it from free core
popj p, ; can't get it. error return
seto t2, ; get a negative one
stor. t2,BIBTim,(t1) ; assume that this message must
; be discarded after being
; sent by setting timer to -1.
hrrz T2,OBFFST(F) ;FIRST BUFFER IN STREAM
stor. t2,BIBMes,(t1) ; put message pointer in place
zero. ,BIBTQ,(t1) ; zero transmission queue pointers
zero. ,BIBRTQ,(t1) ; make sure we end the retran queue
move t2,SndNxt(f) ; next sequence number (after
; this message).
stor. t2,BIBSeq,(t1) ; save it
camg t2,SndLst(f) ; was there anything real here
; (is this sequence number
; after the last we sent?)
pjrst cpopj1## ; no. don't retransmit zero
; length messages. (note that
; this will also be true for
; sends for protocols which
; leave SndNxt and SndLst set to 0.)
movem t2,SndLst(f) ; remember next time that this
; is the last seqnence sent.
zero. ,BIBTim,(t1) ; clear timer so IMPSER knows
; to queue this buffer for
; retransmission.
skipn t2,RetrnQ(f) ; anything in retransmission queue?
jrst MakBi1 ; nope. make this the whole thing
hlrzs t2 ; get end of queue
stor. t1,BIBRTQ,(t2) ; make it point to this new one.
hrlm t1,RetrnQ(f) ; save new end of retrans queue.
pjrst cpopj1## ; return happy
MakBi1: hrls t1 ; get BIB in both first and
; last place.
movem t1,RetrnQ(f) ; save them as the queue description
pjrst cpopj1## ; return happy
subttl FlsBIB
;++
; Functional description:
;
; flush a stream of BIBs link through their retransmission
; queue links.
;
;
; Calling sequence:
;
; move t1,<first BIB>
; pushj p,FlsBIB
; <always returns here>
;
; Input parameters:
;
; t1 - first BIB of BIB chains
;
; Output parameters:
;
; none.
;
; Implicit inputs:
;
; none.
;
; Implicit outputs:
;
; none.
;
; Routine value:
;
; none.
;
; Side effects:
;
; release all BIBs in the chain and all the buffers attached to
; the BIBs.
;--
FlsBIB::
pushj p,save1## ; get p1
FlsBI1: load. p1,BIBNTQ,(t1) ; get next buffer
pushj p,RelBIB ; release last one
jumpe p1,cpopj## ; return is end of the chain
move t1,p1 ; position for next loop
jrst FlsBI1 ; and loop
subttl RelBIB
;++
; Functional description:
;
; flush a BIB and everything that has anything to do with it.
;
;
; Calling sequence:
;
; move t1,BIB
; pushj p,RelBIB or pushj p,ARlBIB
; <always return here>
;
; Input parameters:
;
; T1 - BIB to delete
;
; Output parameters:
;
; none.
;
; Implicit inputs:
;
; BIB data
;
; Implicit outputs:
;
; transmission queue.
;
; Routine value:
;
; none
;
; Side effects:
;
; will remove this BIB from the transmission queue if it finds
; that it is there. if it isn't currently being transmitted,
; it will throw out all it's buffers. if it is being transmitted,
; it will tell IMPSER that this BIB is dead, then it will delete
; it for it when it is done transmitting it.
;
; call at ARlBIB doesn't check for transmission in progress.
;--
RelBIB::
skip. ,BIBTim,(t1),e ; timer set to zero?
jrst ARlBIB ; no. nothing special here.
; yes. this is now being sent
; (or hasn't been sent once!)
decr. t1,BIBTim,(t1) ; set to negative one (-1) to
; tell transmission (at DataNB
; in IMPSER) to flush when done.
popj p, ; and return
; start here to delete without checking for currently begin transmitted
ARlBib::move t2,t1 ; move pointer out of the way.
load. t1,BIBNTQ,(t2) ; get next BIB in tran queue
load. t3,BIBLTQ,(t2) ; and last BIB in tran queue
skipe t1 ; is there a next?
stor. t3,BIBLTQ,(t1) ; yes. make last the last
skipe t3, ; is there a last
stor. t1,BIBNTQ,(t3) ; yes. make next next for it.
load. t1,BIBMes,(t2) ; get the message pointer
push p,t2 ; save BIB address.
pushj p,RelBuf ; release the entire message
pop p,t2 ; get back BIB address.
movei t1,BIBLen/4 ; how many 4 word blocks?
pjrst Giv4Wd## ; release the BIB.
subttl FndDDB
;++
; Functional description:
;
; scan through all the IMP DDBs to find one that matches
; the given values. a zero field in the foreign
; host or foreign port will always match.
;
;
; Calling sequence:
;
; move t1,<his address>
; move t2,<his port>
; move t3,<our port>
; move t4,<protocol>
; pushj p,FndDDB
; <no matching DDB>
; <F set to DDB>
;
; Input parameters:
;
; T1 - address of foriegn host (source)
; T2 - his port number.
; T3 - our port number.
; T4 - protocol (according to IP)
;
; Output parameters:
;
; F - DDB that matches.
;
; Implicit inputs:
;
; DDB chain
;
; Implicit outputs:
;
; none.
;
; Routine value:
;
; returns non-skip if no such DDB is found
;
; Side effects:
;
; none.
;--
FndDDB::pushj p,save2## ; get P1 and P2
movei p1,ImpN## ; load up number of imp DDBs
movei f,ImpDDB## ; point at first one.
FndLp: skipe p2,RmtAdr(f) ; is there a source?
camn t1,p2 ; and is it the right source?
skipa ; yes to one. it's ok.
jrst FndNxt ; not ok
camn t3,LclPrt(f) ; right port for us?
came t4,Protcl(f) ; and right protocol
jrst FndNxt ; no to one or the t'other.
skipe p2,RmtPrt(f) ; is there a remote port?
camn t2,p2 ; the correct one?
pjrst cpopj1## ; good return, DDB in F
FndNxt: hlrz f,DevSer(f) ; get link
sojg p1,FndLp ; loop
popj p, ; never found it: no such DDB
SUBTTL IMP SYSTEM STATISTICS
;IMP SYSTEM STATISTICS -- GETTAB TABLE -1 (WITH SUBTABLES)
DEFINE SUBTBL(USR,SYS) <
<.NT'USR-1>B8 + SYS-IMPGTT
>
$LOW
IMPGTT::
SUBTBL IHM,MESTYP ; 0 %ISIHM IMP-HOST MESSAGES, BY TYPE
subtbl epl,EPLcnt ; 1 %isepl error in previous leader
; messages recieved, by error type
subtbl inc,INCcnt ; 2 %isinc incomplete transmission
; Like a RFNM only error in
; transmission.
SUBTBL DMF,IMPFLT ; 3 %ISDMF IMP DATA MESSAGE FAULTS
SUBTBL BHS,IBFSTT ; 4 %ISBHS IMP BUFFER HANDLING STATISTICS
SUBTBL HMS,SIZHST ; 5 %ISHMS HISTOGRAM OF REC'D DATA
; MESSAGE SIZES
subtbl IPE,IpErrs ; 6 %isIPE errors in IP leader
subtbl IPD,IPData ; 7 %isICD data about IP activities.
subtbl ICE,ICMPEr ; 10 %isIPE errors in IP leader
subtbl ICM,ICMTyp ; 11 %isICM count of recieved ICMP message
; types.
subtbl TCE,TCPErr ; 12 %isTCE errors in TCP message
subtbl TCI,TCPITy ; 13 %isTCI count of input TCP message types
subtbl TCO,TCPOTy ; 14 %isTCO count of ouput TCP message types
;*** ADD MORE GETTAB SUBTABLE POINTERS HERE ***
;FOLLOWING ENTRIES ARE STILL IN THE IMP GETTAB TABLE BUT NOT AT
; FIXED POSITIONS. THE USER MUST GET THE PROPER SUBTABLE POINTER
; FROM THE SET ABOVE, THEN ADD THE DESIRED INDEX INTO THE SUBTABLE.
ImpDat:: ; beginning of data area to be zeroed at init time.
;SUBTABLE 0 %ISIHM IMP-HOST MESSAGE COUNTS. INDEX BY MESSAGE TYPE
MESTYP::BLOCK <.NTIHM==mesdln>
; subtable 1 %isEPL gives count of error in previous leader
; messages received from IMP, broken into error codes.
EPLcnt::block 1 ; 0 %isec0 error flip-flop set
block 1 ; 1 %isec1 message too small ( < 80 bits)
block 1 ; 2 %isec2 message of illegal type.
block 1 ; 3 %isec3 message in wrong format:
; expansions should go here.
EPLmax==:.-EPLcnt ; the highest number we know about
block 1 ; ? %isecu unknown error code
.ntEPL==.-EPLcnt
; subtable 2 %isINC gives count of incomplete transmission
; messages received from IMP, broken down into error codes.
INCcnt::block 1 ; 0 %isin0 Dest Host didn't accept quickly
; enough
block 1 ; 1 %isin1 Message too long
block 1 ; 2 %isin2 Host took to long to transmit
; message to IMP
block 1 ; 3 %isin3 Message lost in network due to
; IMP or circuit failures
block 1 ; 4 %isin4 IMP couldn't accept the entire
; message within 15 sec because of
; unavailable resources
block 1 ; 5 %isin5 Source IMP I/O failure
INCmax==:.-INCcnt ; Max length of table
block 1 ; Unknown error codes
.ntINC==.-INCcnt
;SUBTABLE 3 %ISDMF DATA MESSAGE FAULTS. INDEX BY ITEM NUMBER
IMPFLT:
BADIMP::BLOCK 1 ; 0 %ISIHF IMP INTERFACE HARDWARE FAULTS
BDMLNK::BLOCK 1 ; 1 %ISBDL BAD DATA LINK NUMBERS
BDMMES::BLOCK 1 ; 2 %ISBMT BAD MESSAGE TYPES
BDMRFM::BLOCK 1 ; 4 %ISDDR DISCARDED DATA RFNMS
NODRFM::BLOCK 1 ; 4 %ISSDR SIMULATED (TIMED OUT) DATA RFNMS
SIZERR::BLOCK 1 ; 5 %ISBMS BAD MESSAGE SIZE ERRORS
.NTDMF==.-IMPFLT
;SUBTABLE 4 %ISBHS IMP BUFFER HANDLING STATISTICS. INDEX BY ITEM NUMBER
IBFSTT:
BUFERR::BLOCK 1 ; 0 %ISIBO IMP BUFFER OVERRUNS (RAN OUT OF BUFFERS)
BUFNUM::BLOCK 1 ; 1 %ISNFB NUMBER OF FREE BUFFERS
BUFAVG::BLOCK 1 ; 2 %ISAFB 10↑4 * AVERAGE BUFFER UTILIZATION
.NTBHS==.-IBFSTT
;SUBTABLE 5 %ISHMS HISTOGRAM OF RECEIVED DATA MESSAGE SIZES.
; INDEX BY POWER OF 2
SIZHST::BLOCK <.NTHMS==↑D24>
; subtable 6 %ISIPE internet protocol errors
IpErrs:
IPELed:: block 1 ; %isipl byte stream shorter than IP leader
IPEPrt:: block 1 ; %isipp IP protocol field contained a
; protocol we don't understand.
IPEVer:: block 1 ; %isipv IP version was not the one we
; understand.
IPEChk:: block 1 ; %isipc checksum of IP leader failed.
IPEUOp:: block 1 ; %isipu unknown option seen
.ntIPE==.-IpErrs ; get length of table.
; subtable 7 %isIPD data collected about IP activities
IPData:
IPOpt:: block 1 ; %isIPO number of IP messages with options
IPFrag:: block 1 ; %isIPF number of fragmented messages seen
IPFDun:: block 1 ; %isIFD number of fragmented messages
; actually reassembled.
.ntIPD==.-IPData ; count
; subtable 10 %isICE error counts for ICMP
ICMPEr:
ICMDEr:: block 1 ; %isicd not enough data in stream for ICMP
ICMChk:: block 1 ; %isicc checksum of ICMP message failed.
ICMUnT:: block 1 ; %isicu ICMP message type unknown.
.ntICE==.-ICMPEr ; count
;SUBTABLE 11 %ISICM count of ICMP message types. INDEX BY MESSAGE TYPE
ICMTyp::BLOCK <.NTICM==ICMLen>
; subtable 12 %ISTCE transmission control protocol errors
TCPErr:
TCELed:: block 1 ; %istcl data ends before TCP leader
TCEMes:: block 1 ; %istcm data ends before TCP message
TCEChk:: block 1 ; %istcc checksum error in TCP leader
; and/or message.
TCEPrt:: block 1 ; %istcp incoming connection attempted
; on a port which we don't service.
TCEDDB:: block 1 ; %istcd no DDB when needed
TCEITY:: block 1 ; %istci no ITY when needed
.ntTCE==.-TCPErr ; get the length
; subtable 13 %isTCI TCP input message types. each word is incremented
; whenever a TCP message comes in with the corresponding
; bit on. note that any message can have several
; different bits on, all of which will be counted.
TCPITy:: block <.ntTCI==6> ; six different bits
; subtable 14 %isTCO TCP output message types. each word is incremented
; whenever a TCP message is sent with the corresponding
; bit on. note that any message can have several
; different bits on, all of which will be counted.
TCPOTy:: block <.ntTCO==6> ; six different bits
XP .ISMXL, <<.-IMPGTT-1>←9> ;LENGTH OF GETTAB TABLE, FOR UUOCON
ImpDCn==:ImpDat-. ; negative word count for area to be zeroed on reinit.
$lit
end